home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 6 / MacMania 6.toast / / Tools&Utilities / EnterAct Stuff / Converting text to HTML / move to hAWK programs / $TextToHTML
Encoding:
Text File  |  1996-12-05  |  23.1 KB  |  719 lines  |  [TEXT/KEEN]

  1. # This program generates a set of HTML documents corresponding to a text document,
  2. # one HTML doc for each chapter and a table of contents. Your text document must
  3. # indicate formatting such as titles and list using a specific set of structures
  4. # such as dashed lines and bullets, and this structure must always be just before
  5. # the text to be formatted (additional structure that ends the formatting may
  6. # be placed after the text). Details below.
  7.  
  8. # If your document contains illustrations, you must have created the document with
  9. # EnterAct 3.7 or later (which places all PICTs in the resource fork and numbers
  10. # them 1000, 1001, 1002...1400). More exactly, if you have an old EnterAct document
  11. # you must insert or delete at least one picture using EnterAct 3.7 or later, in
  12. # order to force renumbering of the pictures. If you're not sure, use a resource
  13. # editor to check the numbering of the PICTs in the doc's resource fork.
  14.  
  15. # An overview of the whole process, using "EnterAct 3 Manual" as an example:
  16. # • get a copy of "clip2gif" by Yves Piguet (check your CD's, or Anarchie to Info-Mac)
  17. # • structure your document ("EnterAct 3 Manual"), using EnterAct if you have PICT illustrations
  18. #        (more on this important step below)
  19. # • create a folder to hold the html version of your document, and within it
  20. #     create a folder to hold the gifs ("Disk:...:E3M_HTML:Graphics:")
  21. # • run the script "PICT rsrcs to numbered gifs" from within EnterAct: in the
  22. #     first dialog, select the document to convert ("EnterAct 3 Manual"); in the second
  23. #     dialog, select the folder to hold the gifs ("Graphics"). NOTE to avoid being pestered
  24. #     about where "clip2gif" is, you should open the script using Apple's "Script Editor" first,
  25. #     and then after you have relocated "clip2gif" (you will be asked to do so by Script Editor)
  26. #     do a Save.
  27. # • when "PICT rsrcs to numbered gifs" is done, it presents you with a command
  28. #     line to run this program: select it and hit <enter> to run it. You should also
  29. #    save the command line(s) away somewhere for future reference. It looks like this:
  30. #        hAWK -f$TextToHTML -vgifList="Disk:CW CEDAR:E3M_HTML:Graphics:Unsorted gif list"
  31. #            -- "Disk:CW CEDAR:EnterAct Stuff:Documentation:EnterAct 3 Manual"
  32. #    (it will be stored in the file "$tempScriptResult" until you run your next script with EnterAct)
  33. # • when this program is done, there will be a "Contents.html" file at the top
  34. #     of the folder that holds the html version of your document, and also
  35. #     within it will be a "Text" folder holding the chapter documents, and
  36. #     your folder for the gifs will be chock full of gifs.
  37. # • drag the "Contents.html" file onto your favourite browser and verify that
  38. #     things came out the way you wanted.
  39.  
  40. # If your document contains no illustrations then you don't need to run the
  41. # "PICT rsrcs to numbered gifs" script first. But you still need to construct
  42. # a command line to run this program. First create a folder to hold the results
  43. # (eg "Disk:...:MyDoc HTML:"). Remember the full path names for this folder and for
  44. # your source document ("MyDoc"). Your command line should then look like this:
  45. # hAWK -f$TextToHTML -vgifList="Disk:...:MyDoc HTML:Graphics:Unsorted gif list"
  46. # -- "Disk:...:MyDoc"
  47. # Note that neither the "Graphics" folder nor the file "Unsorted gif list" will
  48. # exist, but you still need to include them in the command line argument. This
  49. # is a minor nuisance, but if you ever decide to include illustrations in your
  50. # document then all you have to do is run the script "PICT rsrcs to numbered gifs", and
  51. # then run the exact same command line that you produced above (or run the
  52. # command line that the script produces, which will be exactly the same).
  53.  
  54.  
  55. # The only tricky bit here is structuring your document so that this program can
  56. # convert the structure into proper html formatting. Characters in your text have to
  57. # clearly signal where headings are, where lists start, and so on. This program is
  58. # set up to handle a specific fixed structure, and if your document doesn't follow
  59. # this structure you'll have to change either your document or this program,
  60. # whichever seems easier. Note however that in all cases these structures must be
  61. # placed just before the text that is to be formatted, though additional structure
  62. # can follow the text to signal the end of formatting.
  63.  
  64. # The "EnterAct 3 Manual" is an example of a document structured for use with
  65. # this program: you might want to browse through it as you read the rules below.
  66.  
  67. # Here are the structuring rules that this program uses by default:
  68. # • First line: presumed to be the title, skip it (the title is instead taken from
  69. #     the name of the document)
  70. # • Each chapter title should be between "dash-space" lines - - - - -,
  71. #     that is one dash-space line before the chapter title, and another
  72. #     dash-space line immediately after. The "dash space" line should begin
  73. #     with a dash '-', and the line should contain only dashes and spaces in
  74. #     any mix you like after the starting dash, at least one additional character
  75. #     after the starting dash.
  76. # • If you have a table of contents in your document, it should be preceded with
  77. #     the chapter title "CONTENTS" (between dash-space lines). The entire table
  78. #     of contents will be skipped, and regenerated by this program. Note your
  79. #     table of contents should be followed by a chapter title, since everything
  80. #     from the "CONTENTS" chapter title to the next chapter title will be skipped.
  81. # • Within each chapter, major subheadings that should be included in the main
  82. #     table of contents should be formatted "§\tSub section name". Subheadings
  83. #     that should NOT be shown in the main table of contents but SHOULD be shown
  84. #     in the table of contents for the chapter itself should be formatted
  85. #     "(§)\tSub section name".
  86. # • Subheadings that should not be shown in any table of contents should take
  87. #     the form ">\tSub section name".
  88. # • Any illustrations (PICT) must have been inserted using EnterAct, and you must
  89. #     have inserted or deleted at least one PICT using v3.7 or later of EnterAct.
  90. # • Major lists begin with "\t•". Sublists begin with "\t\t•". There should be no
  91. #     blank lines within a list, since a blank line signals the end of the list
  92. #     (including any sublists).
  93. # • Chunks of text that are to be quoted as-is with no reformatting should be
  94. #     between lines that consist of exactly four underscores "____".
  95.  
  96. # If you wish to modify the structure that this program uses, you'll need to change
  97. # the function "InitStructurePatterns()" below. Note that structuring information is expected
  98. # to come BEFORE the text to be formatted (in chapter title the dash-space line comes
  99. # before and after the title, but the one after the title is just for the sake of
  100. # appearance in the non-html version). If you want any structuring information to
  101. # come AFTER the text (such as indicating a chapter title by just a dash-space line
  102. # following the title, no dash-space line before it) then you will have to buffer
  103. # the lines as they are read in from your document, since you won't know that
  104. # formatting is required until you've looked at the line after the one that needs
  105. # to be formatted. And you'll have to buffer the output too for the same reason.
  106. # For some help handling this, see
  107. # «hAWK User’s Manual» «R  2   Beyond input records»
  108. # especially the part a couple of pages in, about "End–buffered input".
  109.  
  110. # The function SkipUnwantedSections() looks for specific chapter titles,
  111. # by default just "CONTENTS", and then skips ahead to the next chapter.
  112. # To change which chapter are skipped, modify the first line in this function,
  113. #        if ($0 ~ /^[ \t]*CONTENTS[ \t]*$/)
  114. # to match the names of chapters that should be skipped.
  115.  
  116. # TOC and anchor handling:
  117. # Given "Name of Heading" and heading level H2 or H3:
  118. # 1 replace with <Hn><A NAME = "Name of Heading" >Name of Heading</A></Hn>
  119. # 2 if H2 head, increment h2Counter
  120. # 3 accumulate headings in TOC[h2Counter], with SUBSEP in between
  121. # 4 at end split each array entry, output URLs in unordered lists for TOC.
  122.  
  123. BEGIN {
  124.     InitSpecialCharacters();
  125.     InitStructurePatterns();
  126.     # Remember full name of main document.
  127.     inputFile = ARGV[1];
  128.     # Get title and main head from name of document.
  129.     n = split(inputFile, names, ":");
  130.     theMainTitle = names[n];
  131.     theMainHead = names[n];
  132.     
  133.     contentsMarker = "TOC GOES HERE";
  134.     
  135.     inList = 0;
  136.     listElement = 0;
  137.     h2Counter = 0;
  138.     newParagraphComing = 1;
  139.     
  140.     currentGIF = 0;
  141.     numGIFs = 0;
  142.     doingGIF = 0;
  143.     doingAsIs = 0;
  144.     
  145.     # "gifList", full path to Unsorted gif list, should be preset
  146.     # in dialog or on the command line.
  147.     gifArrayFile = gifList;
  148.     
  149.     outFile = "";
  150.     contentsFileName = "Contents.html";
  151.     
  152.     n = split(gifArrayFile, names, ":");
  153.     for (i = 1; i < n - 1; ++i)
  154.         {
  155.         chaptersFolder = chaptersFolder names[i] ":";
  156.         }
  157.     
  158.     
  159.     graphicsFolderName = names[i];
  160.     gifPartialLocation = "../" graphicsFolderName "/"; # eg "../Graphics/"
  161.     
  162.     contentsFileLocation = chaptersFolder;
  163.     chaptersFolder = chaptersFolder "Text:";
  164.     ## eg chaptersFolder = STDPATH "E3M_HTML:Text:"
  165.     
  166.     MakeFolder(chaptersFolder);
  167.     
  168.     # If doc has no illustrations, make the "Graphics" folder -- life is simpler.
  169.     graphicsFolderPath = contentsFileLocation graphicsFolderName ":";
  170.     MakeFolder(graphicsFolderPath);
  171.     
  172.     LoadGIFNames();
  173.     
  174.     # The main event: inhale all the lines, write the chapters, write main contents.
  175.     DoTheLines();
  176.     WriteMainContentsFile();
  177.     
  178.     # Notify we're done.
  179.     print "HTML conversion of", theMainTitle, "complete.";
  180.     }
  181.  
  182. # Two backslashes are needed before a '&' to use it literally in a quoted pattern
  183. # when doing substitution, otherwise it means "the entire pattern that was matched".
  184. function InitSpecialCharacters()
  185.     {
  186.     ampersand = "\\&";
  187.     lessThan = "\\<";
  188.     greaterThan = "\\>";
  189.     quote = "\\"";
  190.     euroLeft = "\\«";
  191.     euroRight = "\\»";
  192.     bullet = "\\·";
  193.     dornk = "\\¬";
  194.     section = "\\§";
  195.     para = "\\¶";
  196.     cedillaC = "\\ç";
  197.     shy = "\\­";
  198.     copyright = "\\©";
  199.     registration = "\\®";
  200.     question = "\\?";
  201.     
  202.     spaceSub = "_";
  203.     }
  204.  
  205. # NOTE the metacharacters 
  206. # \ ^ $ . [ ] | ( ) * + ? &
  207. # must be preceded by TWO backslashes if you want to match them
  208. # literally in a quoted regular expression. Also note the regular expression
  209. # does NOT overlap the actual text in any case--this allows us to remove
  210. # just the structure signals easily with     sub(structure["thing"], "");
  211. function InitStructurePatterns()
  212.     {
  213.     structure["preformatted"] = "^[ \t]*____[ \t]*$";
  214.     structure["any_list"] = "^[\t]+•[ \t]*";
  215.     structure["top_list"] = "^\t•";
  216.     structure["sub_list"] = "^\t\t•";
  217.     structure["chapter_title"] = "^-[ \t-]+$";
  218.     structure["section_title_shown"] = "^§\t";
  219.     structure["section_title_not_shown"] = "^\\(§\\)\t"; # NOTE the double backslashes
  220.     structure["subsection_title"] = "^>\t";
  221.     structure["gif_marker"] = "^ $";
  222.     }
  223.  
  224. # do for all input lines
  225. function DoTheLines()
  226.     {
  227.     getline < inputFile; # skip the first line
  228.     while ((getline < inputFile) > 0)
  229.         {
  230.         # Stop skipping blank lines if we were doing a GIF and hit nonblank
  231.         if ($0 != "")
  232.             doingGIF = 0;
  233.         
  234.         # "As is" sections shouldn't contain any other "structure"
  235.         if ($0 ~ structure["preformatted"])
  236.             {
  237.             doneFirstPRELine = 0;
  238.             while ((getline < inputFile) > 0)
  239.                 {
  240.                 if ($0 ~ structure["preformatted"])
  241.                     {
  242.                     if (doneFirstPRELine == 1)
  243.                         PrintToOutFile("</PRE>");
  244.                     break;
  245.                     }
  246.                 else
  247.                     {
  248.                     ReplaceSpecialCharacters();
  249.                     if (doneFirstPRELine == 1)
  250.                         PrintToOutFile($0);
  251.                     else
  252.                         {
  253.                         PrintToOutFile("<PRE>" $0);
  254.                         doneFirstPRELine = 1;
  255.                         }
  256.                     }
  257.                 }
  258.             }
  259.         # Remember if list element starting (one or two tabs, bullet)
  260.         else if ($0 ~ structure["any_list"])
  261.             {
  262.             if ($0 ~ structure["top_list"])
  263.                 {
  264.                 # We may be starting a brand new list
  265.                 if (inList == 0)
  266.                     {
  267.                     PrintToOutFile("<UL>");
  268.                     inList = 1;
  269.                     }
  270.                 else
  271.                     {
  272.                     # A new list element ends any subelement
  273.                     if (subListElement == 1)
  274.                         {
  275.                         PrintToOutFile("\t</UL>");
  276.                         subListElement = 0;
  277.                         }
  278.                     }
  279.                 listElement = 1;
  280.                 # Print the first line of the new list element
  281.                 sub(structure["any_list"], "");
  282.                 ReplaceSpecialCharacters();
  283.                 PrintToOutFile("<LI>" $0);
  284.                 }
  285.             else if ($0 ~ structure["sub_list"])
  286.                 {
  287.                 # First subelement, start a new list
  288.                 if (subListElement == 0)
  289.                     {
  290.                     PrintToOutFile("\t<UL>");
  291.                     }
  292.                 subListElement = 1;
  293.                 # Print the first line of the new list subelement
  294.                 sub(structure["any_list"], "");
  295.                 ReplaceSpecialCharacters();
  296.                 PrintToOutFile("\t<LI>" $0);
  297.                 }
  298.             }
  299.         # A list finishes with a blank line (also signals new paragraph)
  300.         else if ($0 == "")
  301.             {
  302.             if (inList)
  303.                 {
  304.                 if (subListElement == 1)
  305.                     PrintToOutFile("\t</UL>");
  306.                 if (listElement == 1)
  307.                     PrintToOutFile("</UL>");
  308.                 inList = 0;
  309.                 listElement = 0;
  310.                 subListElement = 0;
  311.                 }
  312.             # Print blank lines, unless we're skipping GIF space
  313.             if (doingGIF == 0)
  314.                 PrintToOutFile("");
  315.             newParagraphComing = 1;
  316.             }
  317.         # Top level heading H2, between dashed lines
  318.         # This heading starts a new file
  319.         else if ($0 ~ structure["chapter_title"])
  320.             {
  321.             getline < inputFile;
  322.             # Skip the "CONTENTS" section
  323.             SkipUnwantedSections();
  324.             # --having trouble with quotes in chapter titles
  325.             SimplifyQuotes();
  326.             ReplaceSpecialCharacters();
  327.             # make sure we can use text as a file name
  328.             gsub(/\t/, " ");
  329.             gsub(/:/, " ");
  330.             StartNewChapter($0);
  331.             TOC[++h2Counter] = $0 SUBSEP;
  332.             # Skip following dashed line.
  333.             getline < inputFile;
  334.             }
  335.         # Second level heading, shown in main contents
  336.         else if ($0 ~ structure["section_title_shown"])
  337.             {
  338.             sub(structure["section_title_shown"], "");
  339.             ReplaceSpecialCharacters();
  340.             TOC[h2Counter] = TOC[h2Counter] $0 SUBSEP;
  341.             PrintHeading($0, "H3");
  342.             }
  343.         # Second level heading, NOT shown in main contents
  344.         # -- name is preceded with "!" in TOC array to signal that.
  345.         else if ($0 ~ structure["section_title_not_shown"])
  346.             {
  347.             sub(structure["section_title_not_shown"], "");
  348.             ReplaceSpecialCharacters();
  349.             TOC[h2Counter] = TOC[h2Counter] "!" $0 SUBSEP;
  350.             PrintHeading($0, "H3");
  351.             }
  352.         # Third level heading, not in any contents (although it does have an anchor)
  353.         else if ($0 ~ structure["subsection_title"])
  354.             {
  355.             sub(structure["subsection_title"], "");
  356.             ReplaceSpecialCharacters();
  357.             PrintHeading($0, "H4");
  358.             }
  359.         # GIF entry, <option><space> by itself on a line
  360.         else if ($0 ~ structure["gif_marker"])
  361.             {
  362.             PrintGIFTag(gifPartialLocation, gifName[++currentGIF]);
  363.             doingGIF = 1;
  364.             }
  365.         # Regular line, just replace special characters and print it.
  366.         else
  367.             {
  368.             ReplaceSpecialCharacters();
  369.             if (newParagraphComing == 1)
  370.                 PrintToOutFile("<P>" $0);
  371.             else
  372.                 PrintToOutFile($0);
  373.             newParagraphComing = 0;
  374.             }
  375.         }
  376.     }
  377.  
  378. # Load AND sort the gif names, to gifName[ 1..numGIFs ].
  379. # (gif name format is "arbtext#ddddd.gif" where d is a digit)
  380. function LoadGIFNames(        x, p, a, b, numSpot, numA, trueP, i)
  381.     {
  382.     numGIFs = 0;
  383.     numA = 0;
  384.     
  385.     if (exists(gifArrayFile))
  386.         {
  387.         while ((getline x < gifArrayFile) > 0)
  388.             p[++numGIFs] = x;
  389.         for (i = 1; i <= numGIFs; ++i)
  390.             {
  391.             numSpot = match(p[i], /#[0-9]+/);
  392.             # allow other files in folder, or other text in list
  393.             if (numSpot > 0)
  394.                 {
  395.                 a[++numA] = substr(p[i], numSpot+1, RLENGTH-1);
  396.                 trueP[numA] = p[i];
  397.                 }
  398.             }
  399.         if (numA+0 > 0)
  400.             {
  401.             sort(a,b,"n");
  402.             for (i = 1; i <= numA; ++i)
  403.                 {
  404.                 gifName[i] = trueP[b[i]];
  405.                 }
  406.             }
  407.         numGIFs = numA;
  408.         }
  409.     }
  410.  
  411. # Print to specific file, if there is one.
  412. function PrintToOutFile(s)
  413.     {
  414.     if (outFile != "")
  415.         print s > outFile;
  416.     }
  417.  
  418. function ReplaceSpecialCharacters()
  419.     {
  420.     gsub(/\&/, ampersand); # keep this one first
  421.     gsub(/</, lessThan);
  422.     gsub(/>/, greaterThan);
  423.     gsub(/«/, euroLeft);
  424.     gsub(/»/, euroRight);
  425.     gsub(/•/, bullet);
  426.     gsub(/¬/, dornk);        # does this have a real name?
  427.     gsub(/§/, section);
  428.     gsub(/¶/, para);
  429.     gsub(/ç/, cedillaC);
  430.     gsub(/—/, shy);
  431.     gsub(/©/, copyright);
  432.     gsub(/®/, registration);
  433.     
  434.     # Question mark gives trouble in anchors, do it too
  435.     #gsub(/\?/, question);
  436.     
  437.     # Short dash -- where is it in the ISO Latin-1 set??
  438.     gsub(/–/, "-");
  439.     # Ditto "…"
  440.     gsub(/…/, "...");
  441.     # And hey, where's ƒ?
  442.     gsub(/ƒ/, "f");
  443.     
  444.     # straighten out the quotes and ticks
  445.     gsub(/“/, "\"");
  446.     gsub(/”/, "\"");
  447.     gsub(/‘/, "'");
  448.     gsub(/’/, "'");
  449.     # do quotes last since we may have generated some new ones
  450.     gsub(/"/, quote);
  451.     }
  452.  
  453. function SimplifyQuotes()
  454.     {
  455.     gsub(/“/, "'");
  456.     gsub(/”/, "'");
  457.     gsub(/‘/, "'");
  458.     gsub(/’/, "'");
  459.     gsub(/"/, "'");
  460.     }
  461.  
  462. # Skip the "CONTENTS" section. This is called for the beginning of all chapters,
  463. # so you could add a counter and selectively skip more than one chapter in different
  464. # places throughout your document.
  465. function SkipUnwantedSections()
  466.     {
  467.     if ($0 ~ /^[ \t]*CONTENTS[ \t]*$/)
  468.         {
  469.         getline < inputFile;
  470.         while ((getline < inputFile) > 0)
  471.             {
  472.             if ($0 ~ structure["chapter_title"])
  473.                 {
  474.                 getline < inputFile;
  475.                 break;
  476.                 }
  477.             }
  478.         }
  479.     }
  480.  
  481. # Finish writing current chapter, if any. Start a new temp file for
  482. # next chapter (tack "x" onto chapter name for the temp version)
  483. # and pump out the starting HTML.
  484. function StartNewChapter(chapterName,        truncatedName, nameLength)
  485.     {
  486.     if (outFile != "")
  487.         FinishCurrentChapter();
  488.     truncatedName = TempFileNameForChapter(chapterName);
  489.     outFile = chaptersFolder truncatedName;
  490.     StartHTML(chapterName);
  491.     }
  492.  
  493. # Clean name, append .html, keep name short enuff.
  494. function TempFileNameForChapter(chapterName,        fileName, nameLength)
  495.     {
  496.     fileName = chapterName ".html" "x";
  497.     nameLength = length(fileName);
  498.     if (nameLength > 31)
  499.         fileName = substr(chapterName, 1, 25) ".html" "x";
  500.     gsub(/ /, spaceSub, fileName);
  501.     return fileName;
  502.     }
  503.  
  504. function FileNameForChapter(chapterName,        fileName, tempName, nameLength)
  505.     {
  506.     tempName = TempFileNameForChapter(chapterName);
  507.     nameLength = length(tempName);
  508.     fileName = substr(tempName, 1, nameLength - 1);
  509.     return fileName;
  510.     }
  511.  
  512. # Close temp file for chapter; copy it to final version, inserting
  513. # TOC at top; delete temp file.
  514. function FinishCurrentChapter(        nameLength)
  515.     {
  516.     PrintToOutFile("<P>");
  517.     DoChapterTOC();
  518.     EndHTML();
  519.     close(outFile);
  520.     oldOutFile = outFile;
  521.     nameLength = length(outFile);
  522.     outFile = substr(outFile, 1, nameLength - 1);
  523.     WriteFinalChapter();
  524.     close(outFile);
  525.     close(oldOutFile);
  526.     remove(oldOutFile);
  527.     # temporarily, we have no outFile to write to
  528.     outFile = "";
  529.     }
  530.  
  531. function StartHTML(chapterName)
  532.     {
  533.     PrintToOutFile("<HTML>");
  534.     PrintToOutFile("");
  535.     PrintToOutFile("<HEAD>");
  536.     PrintToOutFile("<TITLE>" chapterName "</TITLE>");
  537.     PrintToOutFile("</HEAD>");
  538.     PrintToOutFile("");
  539.     PrintToOutFile("<BODY>");
  540.     PrintToOutFile("<H1>" chapterName "</H1>");
  541.     PrintToOutFile("<HR>");
  542.     PrintToOutFile("");
  543.     PrintToOutFile(contentsMarker); # table of contents goes here on 2nd pass
  544.     }
  545.  
  546. function EndHTML()
  547.     {
  548.     PrintToOutFile("");
  549.     PrintToOutFile("</BODY>");
  550.     PrintToOutFile("");
  551.     PrintToOutFile("</HTML>");
  552.     PrintToOutFile("");
  553.     PrintToOutFile("");
  554.     }
  555.  
  556. # Print a heading and named anchor. "level" should be "H2", "H3" etc.
  557. # Having trouble with "?" in name, so leave it out of anchor name.
  558. function PrintHeading(name, level)
  559.     {
  560.     PrintToOutFile("<" level "><A NAME = \"" NoQuestionVersionOf(name) "\" >" name "</A></" level ">");
  561.     }
  562.  
  563. # Replace question marks, and spaces.
  564. function NoQuestionVersionOf(name)
  565.     {
  566.     gsub(/\?/, "", name);
  567.     gsub(/ /, spaceSub, name);
  568.     return name;
  569.     }
  570.  
  571. # All pictures are in ":Graphics:" beside ":Text:", and so "theLocation"
  572. # says go one level up and then down into Text.
  573. function PrintGIFTag(theLocation, theGIFName,        copyOfName)
  574.     {
  575.     PrintToOutFile("<P>");
  576.     # One little wrinkle, turn the "#" in name into "%23"
  577.     copyOfName = theGIFName;
  578.     sub(/#/, "%23", copyOfName);
  579.     PrintToOutFile("<IMG SRC=\"" theLocation copyOfName "\" ALIGN = \"top\">");
  580.     PrintToOutFile("<P>");
  581.     }
  582.  
  583. # The main table of contents.
  584. # We just print two levels. Additional levels would probably need additional
  585. # counters h3Counter, h4Counter etc and additional arrays.
  586. function DoTOC(        i, j, numSubHeads, contents, showSubs)
  587.     {
  588.     PrintToOutFile("<H2><A NAME = \"Table_of_Contents\">" " Table of Contents " "</A></H2>");
  589.     PrintToOutFile("<UL>");
  590.     for (i = 1; i <= h2Counter; ++i)
  591.         {
  592.         numSubHeads = split(TOC[i], contents, SUBSEP);
  593.         if (contents[numSubHeads] == "")
  594.             --numSubHeads;
  595.         
  596.         # Print the main heading, href is file corresponding to chapter
  597.         PrintToOutFile("<LI> <A HREF = \"Text/" FileNameForChapter(contents[1]) "\"> " contents[1] " </A>");
  598.         
  599.         # then print the subheadings
  600.         if (numSubHeads > 1)
  601.             {
  602.             # Check there are some headings to show - don't show if name starts with "!"
  603.             showSubs = 0;
  604.             for (j = 2; j <= numSubHeads; ++j)
  605.                 {
  606.                 if (index(contents[j], "!") != 1)
  607.                     {
  608.                     showSubs = 1;
  609.                     break;
  610.                     }
  611.                 }
  612.             if (showSubs == 1)
  613.                 {
  614.                 PrintToOutFile("\t<UL>");
  615.                 for (j = 2; j <= numSubHeads; ++j)
  616.                     {
  617.                     # href consists of location, file name (from chapter name), "#", subsection name
  618.                     if (index(contents[j], "!") != 1)
  619.                         PrintToOutFile("\t<LI> <A HREF = \"Text/" FileNameForChapter(contents[1]) "#" NoQuestionVersionOf(contents[j]) "\"> " contents[j] " </A>");
  620.                     }
  621.                 PrintToOutFile("\t</UL>");
  622.                 }
  623.             }
  624.         }
  625.     PrintToOutFile("</UL>");
  626.     }
  627.  
  628. function DoChapterTOC(        i, j, numSubHeads, contents)
  629.     {
  630.     # Print link to main table of contents
  631.     PrintToOutFile("<A HREF = \"../" contentsFileName "#Table_of_Contents\">Main Contents</A>");
  632.     
  633.     # Print chapter's table of contents
  634.     i = h2Counter;
  635.     numSubHeads = split(TOC[i], contents, SUBSEP);
  636.     if (contents[numSubHeads] == "")
  637.         --numSubHeads;
  638.     # Print the main heading
  639.     PrintToOutFile("<H2> <A HREF = \"#" NoQuestionVersionOf(contents[1]) "\"> " contents[1] " </A></H2>");
  640.     if (numSubHeads > 1)
  641.         {
  642.         PrintToOutFile("\t<UL>");
  643.         for (j = 2; j <= numSubHeads; ++j)
  644.             {
  645.             # Trim any leading "!"
  646.             if (index(contents[j], "!") == 1)
  647.                 contents[j] = substr(contents[j], 2);
  648.             PrintToOutFile("\t<LI> <A HREF = \"#" NoQuestionVersionOf(contents[j]) "\"> " contents[j] " </A>");
  649.             }
  650.         PrintToOutFile("\t</UL>");
  651.         }
  652.     }
  653.  
  654. function WriteFinalChapter(        haveSeenContents)
  655.     {
  656.     haveSeenContents = 0; #speed things up with a simple "boolean"
  657.     
  658.     # Get lines from oldOutFile to the variable line.
  659.     while (getline line < oldOutFile > 0)
  660.         {
  661.         if (haveSeenContents == 0 && line ~ contentsMarker)
  662.             {
  663.             DoChapterTOC();
  664.             PrintToOutFile("");
  665.             haveSeenContents = 1;
  666.             }
  667.         else
  668.             PrintToOutFile(line);
  669.         }
  670.     }
  671.  
  672. # Write the main file, table of contents at one level above the chapter documents.
  673. # Finish any open chapter first.
  674. function WriteMainContentsFile()
  675.     {
  676.     if (outFile != "")
  677.         FinishCurrentChapter();
  678.     
  679.     outFile = contentsFileLocation contentsFileName;
  680.     
  681.     PrintToOutFile("<HTML>");
  682.     PrintToOutFile("");
  683.     PrintToOutFile("<HEAD>");
  684.     PrintToOutFile("<TITLE>" theMainTitle "</TITLE>");
  685.     PrintToOutFile("</HEAD>");
  686.     PrintToOutFile("");
  687.     PrintToOutFile("<BODY>");
  688.     PrintToOutFile("<H1>" theMainHead "</H1>");
  689.     PrintToOutFile("<HR>");
  690.     PrintToOutFile("");
  691.     
  692.     DoTOC();
  693.     
  694.     PrintToOutFile("");
  695.     PrintToOutFile("</BODY>");
  696.     PrintToOutFile("");
  697.     PrintToOutFile("</HTML>");
  698.     PrintToOutFile("");
  699.     PrintToOutFile("");
  700.     
  701.     close(outFile);
  702.     }
  703.  
  704. # Working within the current bounds of hAWK, we can (just barely) persuade
  705. # a folder to come into existence by using "copy", which creates folders
  706. # along the specified path if possible. So we make a file, copy it to the
  707. # folder we want to exist, and then remove both versions of the file. Ugh.
  708. function MakeFolder(folderPathName,     xFile, xFileSource, xFileDest)
  709.     {
  710.     xFile = "Temp1342134HIKE!";
  711.     xFileSource = STDPATH xFile;
  712.     xFileDest = folderPathName xFile;
  713.     print "Hello" > xFileSource;
  714.     close(xFileSource);
  715.     copy(xFileSource, xFileDest);
  716.     remove(xFileSource);
  717.     remove(xFileDest);
  718.     }
  719.